﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Collections.Concurrent;
using System.Threading;

namespace AspNetSimple
{
    public partial class frmMain : Form
    {
        public class Teacher
        {
            public string Href { get; set; }
            public string Title { get; set; }
            public string Content { get; set; }
            public string Phone { get; set; }
            public string Name { get; set; }
            public string Email { get; set; }
            public string Subject { get; set; }
            public string Interest { get; set; }
            public string Courses { get; set; }
            public string Achievement { get; set; }
        }

        public frmMain()
        {
            InitializeComponent();
            webBrowserHtml.DocumentCompleted += Navigated;
            webBrowserDetail.DocumentCompleted += DetailCompleted;
            TaskQueue();
        }

        private void DetailCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            MyWebBrowser browser = (sender as MyWebBrowser);
            string url = browser.Url.ToString();
            string path = browser.Url.PathAndQuery;
            // Console.WriteLine("[Detail] Navigate: {0}", url);
            browser.Document.Window.Error += (sender1, e1) =>
            {
                e1.Handled = true;
            };
            string sex = null;
            string lanmu = null;
            string title = null;
            string phone = null;
            string email = null;
            string subject = null;
            string interest = null;
            string experience = null;
            string courses = null;
            string achievement = null;
            var elementCollection = browser.Document.Body.GetElementsByTagName("div");
            //
            foreach (HtmlElement item in elementCollection)
            {
                string css = item.GetAttribute("className");
                if (css.Contains("field--name-field-sex"))
                {
                    sex = item.GetElementsByTagName("div")[1].InnerText;
                }
                else if (css.Contains("field--name-field-lanmu"))
                {
                    lanmu = item.GetElementsByTagName("div")[1].InnerText;
                }
                else if (css.Contains("field--name-field-telephone"))
                {
                    phone = item.GetElementsByTagName("div")[1].InnerText;
                }
                else if (css.Contains("field--name-field-email"))
                {
                    email = item.GetElementsByTagName("div")[1].InnerText;
                }
                else if (css.Contains("field--name-field-subject"))
                {
                    subject = item.GetElementsByTagName("div")[1].InnerText;
                    if (!string.IsNullOrEmpty(subject))
                    {
                        subject = subject.Replace("\r\n", "|");
                    }
                }
                else if (css.Contains("field--name-field-interest"))
                {
                    interest = item.GetElementsByTagName("div")[1].InnerText;
                    if (!string.IsNullOrEmpty(interest))
                    {
                        interest = interest.Replace("\r\n", "|");
                    }
                }
                else if (css.Contains("field--name-field-experience"))
                {
                    experience = item.GetElementsByTagName("div")[1].InnerText;
                    if (!string.IsNullOrEmpty(experience))
                    {
                        experience = experience.Replace("\r\n", "|");
                        experience = experience.Replace(" ", "");
                    }
                }
                else if (css.Contains("field--name-field-courses"))
                {
                    courses = item.GetElementsByTagName("div")[1].InnerText;
                    if (!string.IsNullOrEmpty(courses))
                    {
                        courses = courses.Replace("\r\n", "|");
                        courses = courses.Replace(" ", "");
                    }
                }
                else if (css.Contains("field--name-field-achievement"))
                {
                    achievement = item.GetElementsByTagName("div")[1].InnerText;
                    if (!string.IsNullOrEmpty(achievement))
                    {
                        achievement = achievement.Replace("\r\n", "|");
                        achievement = achievement.Replace(" ", "");
                    }
                }
            }

            var ele1 = browser.Document.Body.GetElementsByTagName("span");
            foreach (HtmlElement item in ele1)
            {
                string css = item.GetAttribute("className");

                if (css.Contains("field--name-title"))
                {
                    title = item.InnerText;
                }
            }

            if (!string.IsNullOrEmpty(title) && !string.IsNullOrEmpty(sex)) Console.WriteLine("[{3}],{0},{1},{2},{4},{5},{6},{7},{8},{9},{10}", url, title, sex, lanmu, phone, email, subject, interest, experience, courses, achievement);

            Teacher teacher = new Teacher
            {
                Achievement = achievement,
                Content = title,
                Href = url,
                Courses = courses,
                Email = email,
                Interest = interest,
                Name = title,
                Phone = phone,
                Subject = subject,
                Title = title
            };

            teachers.Add(teacher);
        }
        private Thread thread;
        ConcurrentQueue<Teacher> queue = new ConcurrentQueue<Teacher>();
        private void TaskQueue()
        {
            thread = new Thread(new ThreadStart(() =>
              {
                  while (true)
                  {
                      if (webBrowserDetail.InvokeRequired)
                      {
                          webBrowserDetail.Invoke(new MethodInvoker(() =>
                          {
                              if (!webBrowserDetail.IsBusy)
                              {
                                  Teacher item;
                                  if (queue.TryDequeue(out item))
                                  {
                                      webBrowserDetail.Navigate(item.Href);
                                      webBrowserDetail.ScriptErrorsSuppressed = false;
                                  }
                              }
                          }));

                          Thread.Sleep(200);
                      }
                  }
              }));
            thread.Start();
        }
        private List<Teacher> teachers = new List<Teacher>();
        private void buttonNavigate_Click(object sender, EventArgs e)
        {
            string url = textBoxUrl.Text;
            if (!string.IsNullOrEmpty(url) && url.IndexOf("http") == 0)
            {
                teachers.Clear();
                Navigate(url);
            }
        }
        List<Teacher> posts = new List<Teacher>();
        private string navigatePostName = null;
        private void Employee(string postName, List<Teacher> employees)
        {
            foreach (var item in employees)
            {
                // Console.WriteLine("[{3}] - {0},{1},{2}", item.Href, item.Title, item.Content, postName);
                queue.Enqueue(item);
            }
        }
        private void Post(string href, List<Teacher> post)
        {
            Teacher next = null;
            foreach (var item in post)
            {
                if (!posts.Any(c => c.Href == item.Href))
                {
                    posts.Add(item); next = item; break;
                }
            }

            if (next != null) { navigatePostName = next.Content; Navigate(next.Href); }
        }


        private void Navigate(string url)
        {
            webBrowserHtml.Navigate(url);
            webBrowserHtml.ScriptErrorsSuppressed = false;
        }

        private void Navigated(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            MyWebBrowser browser = (sender as MyWebBrowser);
            string url = browser.Url.ToString();
            string path = browser.Url.PathAndQuery;
            // Console.WriteLine("Navigate: {0}", url);
            ((SHDocVw.WebBrowser)browser.ActiveXInstance).Silent = true;
            browser.Document.Window.Error += (sender1, e1) =>
            {
                e1.Handled = true;
            };
            var elementCollection = browser.Document.Body.GetElementsByTagName("a");
            List<Teacher> post = new List<Teacher>();
            List<Teacher> employee = new List<Teacher>();
            foreach (HtmlElement item in elementCollection)
            {
                string title = item.GetAttribute("title");
                string href = item.GetAttribute("href");
                string content = item.InnerText;

                Regex regex = new Regex("/\\d{3,4}$");
                Regex regex1 = new Regex("\\s*r$");
                if (regex.IsMatch(href))
                {
                    //Console.WriteLine("[Employee] - {0},{1},{2}", href, title, content);
                    employee.Add(new Teacher { Href = href, Content = content, Title = title });
                }
                else if (regex1.IsMatch(href) && href.Contains("http://lifesciences.sysu.edu.cn/teachers/"))
                {
                    //Console.WriteLine("Post - {0},{1},{2}", href, title, content);

                    if (!post.Any(c => c.Href == href))
                    {
                        post.Add(new Teacher { Href = href, Content = content, Title = title });
                    }
                }
            }
            if (!string.IsNullOrEmpty(navigatePostName)) Employee(navigatePostName, employee);
            Post(url, post);
        }

        private void buttonBitmap_Click(object sender, EventArgs e)
        {
            WebBrowserConvert.Default.Completed += bitmap =>
            {
                pictureBoxBitmap.Image = bitmap;
            };
            WebBrowserConvert.Default.ToBitmap(new Uri(textBoxUrl.Text));
        }

        private void buttonDetail_Click(object sender, EventArgs e)
        {
            webBrowserDetail.Navigate(textBoxUrl.Text);
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                if (thread != null) { thread.Abort(); }
            }
            catch { }
        }
    }
}
